//require支持加载的文件 .js/ .json/ .node
// .js -> module.exports/exports
// .json -> JSON.pares
// .node -> process.dlopen
// 如果加载的并不是以上文件，默认会以.js文件来解析
const path = require('path');
const semver =require('semver') //版本号检查工具
const colors = require('colors/safe') //颜色工具
const userHome = require('user-home') //获取用户主目录
const pathExists = require('path-exists').sync //检查目录是否存在
const commander = require('commander')
const log = require('@hjx-cli-lerna/log')//日志输出工具
const exec = require('@hjx-cli-lerna/exec')//初始化项目
const pkg = require('../package.json')
const constant = require('./const')

let args;
const program = new commander.Command();

async function core(){
  try {
    //启动检查
    await prepare()
    //注册脚手架命令
    registerCommand()
  }catch (e){
    log.error(e.message)
  }
}

//注册脚手架命令
function registerCommand(){
  program
    .name(Object.keys(pkg.bin)[0]) //脚手架名称
    .usage('<command> [options]') //使用提示
    .version(pkg.version) //脚手架版本
    .option('-d, --debug', '是否开启调试模式', false) //debug属性注册
    .option('-tp, --targetPath <targetPath>', '是否启用本地调试文件路径', '');


  //命令注册
  program
    .command('init [projectName]')
    .option('-f, --force', '是否强制初始化项目')
    .action(exec);

  //监听是否开启debug模式
  program.on('option:debug', function (){
    if (this.opts().debug){
      process.env.LOG_LEVEL = 'verbose'
    } else {
      process.env.LOG_LEVEL = 'info'
    }
    log.level = process.env.LOG_LEVEL
    log.verbose('test', 'debug')
  });

  //指定targetPath
  program.on('option:targetPath',function (){
    process.env.CLI_TARGET_PATH = program.opts().targetPath
  })

  //未知命令监听
  program.on('command:*', function (obj){
    //获取所有可用命令
    const availableCommands = program.commands.map(cmd => cmd.name())
    console.log(colors.red('未知的命令：'+obj[0]))
    if(availableCommands.length > 0){
      console.log(colors.red('可用命令为：'+availableCommands.join(',')))
    }
  });
  //未输入命令参数,默认打印帮助提示
  if(process.argv.length < 3){
    program.outputHelp()
  }
  program.parse(process.argv)

}

async function prepare(){
   //检查版本
   checkPkgVersion()

   //检查操作系统登录用户
   checkRoot()
   //获取用户主目录
   checkUserHome()
   checkEnv()
   //检查是否是最新版本，不是则提示更新
   await checkGlobalUpdate()
 }

//检查是否是最新版本，不是则提示更新
async function checkGlobalUpdate(){
  //1、获取当前版本号和模块名
  const currentVersion = pkg.version
  const npmName = pkg.name
  //2、调用npm API, 获取最新版本号
  //3、提取所有版本号，对比哪些版本号是大于当前版本号
  //4、获取最新的版本号，提示用户更新到该版本
  const { getNpmSemverVersion } = require('@hjx-cli-lerna/get-npm-info');
  const lastVersion = await getNpmSemverVersion(currentVersion ,npmName)
  if(lastVersion && semver.gt(lastVersion, currentVersion)){
    log.warn(colors.yellow('更新提示',`请手动更新${npmName},当前版本：${currentVersion}，最新版本${lastVersion} 
         更新命令：npm install -g ${npmName}`))
  }
}

//检查环境变量
function checkEnv(){
  const dotenv = require('dotenv');
  //读取根目录环境配置文件
  const dotenvPath = path.resolve(userHome, '.env')
  //检查根目录是否有.env文件
  if(pathExists(dotenvPath)){
   dotenv.config({
      path: dotenvPath
    });
  }
  createDefaultConfig()
}

//创建默认篇配置
function createDefaultConfig(){
  const cliConfig = {
    home: userHome,
  }
  if(process.env.CLI_HOME){
    cliConfig['cliHome'] = path.join(userHome, process.env.CLI_HOME)
  } else {
    cliConfig['cliHome'] = path.join(userHome, constant.DEFAULT_CLI_HOME)
  }
  process.env.CLI_HOME_PATH = cliConfig.cliHome
}

//获取用户主目录
function checkUserHome(){
  if(!userHome || !pathExists(userHome)){
    throw new Error(colors.red('当前登录用户主目录不存在'))
  }
}

//检查版本号
function checkPkgVersion(){
  log.info('cli', pkg.version)
}

//检查当前服务器的登录用户
function checkRoot(){
  const rootCheck = require('root-check');
  rootCheck()
}

module.exports = core